/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package view;

import control.ShopFacade;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.Date;
import java.util.List;
import javafx.application.Platform;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.scene.control.Button;
import javafx.scene.control.ComboBox;
import javafx.scene.control.Label;
import javafx.scene.control.ListCell;
import javafx.scene.control.TableCell;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.scene.control.TextField;
import javafx.scene.control.cell.ComboBoxTableCell;
import javafx.scene.control.cell.PropertyValueFactory;
import javafx.scene.control.cell.TextFieldTableCell;
import javafx.scene.layout.HBox;
import javafx.scene.layout.VBox;
import javafx.scene.text.Text;
import javafx.util.StringConverter;
import jfxtras.labs.scene.control.BeanPathAdapter;
import jpamodel.Category;
import jpamodel.CommissionWare;
import jpamodel.Seller;

/**
 *
 * @author Hans
 */
public class CommissionsView extends VBox {

    private TableView<CommissionWare> table = new TableView<>();
    private ObservableList<CommissionWare> datalist;// = FXCollections.observableArrayList();
    private ObservableList<CommissionWare> sortedList;
    private ObservableList<Seller> sellers;
    private ShopFacade shop;
    private ObservableList<Category> cats;
//    private ObservableList<String> cats = FXCollections.observableArrayList("Møbler", "Dametøj", "Herretøj", "Børn", "Indretning", "Diverse", "Alt");

    private Text text;
    private TableColumn<CommissionWare, String> name;
    private TableColumn<CommissionWare, Seller> seller;
    private TableColumn<CommissionWare, Number> priceColumn;
    private TableColumn<CommissionWare, Date> dateIn;
    private TableColumn<CommissionWare, Date> dateOut;
    private TableColumn<CommissionWare, Number> comVal;
    private DateTimeFormatter myDateFormatter = DateTimeFormatter.ofPattern("dd-MM-yyyy");
    private SimpleDateFormat sdf = new SimpleDateFormat("dd-MM-yyyy");
    private HBox top;
    private ComboBox<Category> categoryCombo;
    private Button sellWare, editPrice, deleteWare;
    private TextField newPrice;
    private Label wareName;
    private CommissionWare selectedWare;
    private final CommissionWare commissionWare = new CommissionWare();
    private final BeanPathAdapter<CommissionWare> commissionWareAdapter = new BeanPathAdapter<>(commissionWare);

    public CommissionsView(ObservableList<CommissionWare> data, ObservableList<Seller> sellerdata, ShopFacade shop) {
        this.sortedList = FXCollections.observableArrayList();
        sellers = sellerdata;
        this.text = new Text("* Varer i Kommission *");
        this.comVal = new TableColumn<>("Kom");
        this.dateOut = new TableColumn<>("Dato solgt");
        this.dateIn = new TableColumn<>("Dato ind");
        this.priceColumn = new TableColumn<>("Pris");
        this.seller = new TableColumn<>("Sælger");
        this.name = new TableColumn<>("Vare");
        this.datalist = data;
        this.shop = shop;
        if (shop.getDBC().isConnected()) {
            datalist = shop.getAllCommissionWares();
            datalist.stream().forEach((ware) -> {
                sortedList.add(ware);
            });
            cats = shop.getCategories(false);
        }
        this.setPadding(MainView.INSETS);
        table.setItems(sortedList);
        table.getStyleClass().add("table");
        table.getColumns().add(name);
        table.getColumns().add(seller);
        table.getColumns().add(priceColumn);
        table.getColumns().add(comVal);
        table.getColumns().add(dateIn);
        table.getColumns().add(dateOut);
        table.setPrefWidth(MainView.WIDTH);
        text.setFont(MainView.getFont());

        commissionWareAdapter.bindContentBidirectional("name", null, String.class, table.getItems(), null, null, null);
        commissionWareAdapter.bindContentBidirectional("seller", "name", String.class, table.getItems(), null, null, null);
        commissionWareAdapter.bindContentBidirectional("currentPrice", null, Number.class, table.getItems(), null, null, null);
        commissionWareAdapter.bindContentBidirectional("commission", null, Number.class, table.getItems(), null, null, null);
        commissionWareAdapter.bindContentBidirectional("dateOut", null, Date.class, table.getItems(), null, null, null);
        commissionWareAdapter.bindContentBidirectional("dateIn", null, Date.class, table.getItems(), null, null, null);
        name.setCellValueFactory(new PropertyValueFactory<>("name"));
        seller.setCellValueFactory(new PropertyValueFactory<>("seller"));
        priceColumn.setCellValueFactory(new PropertyValueFactory<>("currentPrice"));
        dateIn.setCellValueFactory(new PropertyValueFactory<>("dateIn"));
        dateOut.setCellValueFactory(new PropertyValueFactory<>("dateOut"));
        comVal.setCellValueFactory(new PropertyValueFactory<>("commission"));
        setupComboBox();
        top = new HBox(text, categoryCombo);
        top.setSpacing(20);
        this.getChildren().addAll(top, table);//text, 0, 0);
        setupButtons();
        priceColumn.getStyleClass().add("numbercolums");
        comVal.getStyleClass().add("numbercolums");
        table.setEditable(true);
        name.setCellFactory(TextFieldTableCell.forTableColumn());
        name.setOnEditCommit(t -> {
            t.getRowValue().setName(t.getNewValue());
            shop.persist(t.getRowValue());
        });
        name.prefWidthProperty().bind(table.widthProperty().multiply(0.20));
        priceColumn.prefWidthProperty().bind(table.widthProperty().multiply(0.10));
        comVal.prefWidthProperty().bind(table.widthProperty().multiply(0.10));
        seller.prefWidthProperty().bind(table.widthProperty().multiply(0.20));
        dateIn.prefWidthProperty().bind(table.widthProperty().multiply(0.20));
        dateOut.prefWidthProperty().bind(table.widthProperty().multiply(0.20));
        seller.setCellFactory(ComboBoxTableCell.forTableColumn(sellers));
        seller.setOnEditCommit(e -> {
            Seller s = e.getNewValue();
            if (s != null) {
                CommissionWare w = e.getRowValue();
                w.setSeller(s);
                shop.persist(w);
                shop.persist(s);
            }
        });
//        dateIn.setCellValueFactory(c -> c.getValue().dateInProperty());
        dateIn.setCellFactory(c -> {
            return new TableCell<CommissionWare, Date>() {
                @Override
                protected void updateItem(Date item, boolean empty) {
                    super.updateItem(item, empty);

                    if (item == null || empty) {
                        setText(null);
                        setStyle("");
                    } else {
                        // Format date.
                        setText(sdf.format(item));
                    }
                }
            };
        });
//        dateOut.setCellValueFactory(c -> c.getValue().dateOutProperty());
        dateOut.setCellFactory(c -> {
            return new TableCell<CommissionWare, Date>() {
                @Override
                protected void updateItem(Date item, boolean empty) {
                    super.updateItem(item, empty);

                    if (item == null || empty) {
                        setText(null);
                        setStyle("");
                    } else {
                        // Format date.
                        setText(sdf.format(item));
                    }
                }
            };
        });

        table.getSelectionModel().selectedItemProperty().addListener(
                (observable, oldValue, newValue) -> selectedWare(newValue));

    }

    private void setupButtons() {
        wareName = new Label(" ");
        sellWare = new Button("Sælg Vare");
        sellWare.getStyleClass().add("mybutton");
        editPrice = new Button("Ny Pris");
        editPrice.getStyleClass().add("mybutton");
        newPrice = new IntegerTextField();
        HBox priceBox = new HBox(editPrice, newPrice);
        priceBox.setSpacing(20);
        deleteWare = new Button("Slet Vare");
        deleteWare.getStyleClass().add("mybutton");
        this.getChildren().addAll(wareName, sellWare, priceBox, deleteWare);

        sellWare.setOnAction(event -> {
            if (selectedWare != null && selectedWare.isUnsold()) {
                selectedWare.setLocalDateOut(LocalDate.now());
                selectedWare.setDateOut(new Date());
                System.out.println(selectedWare.getDateOut().toString());
                shop.persist(selectedWare);
                commissionWareAdapter.setBean(selectedWare);
                refreshTable();
            }
        });

        editPrice.setOnAction(event -> {
            if (selectedWare != null && selectedWare.isUnsold() && !newPrice.getText().isEmpty()) {
                int price = Integer.parseInt(newPrice.getText());
                selectedWare.setCurrentPrice(price);
                shop.persist(selectedWare);
                newPrice.clear();
                refreshTable();
            }
        });

        deleteWare.setOnAction(event -> {
            if (selectedWare != null) {
                shop.remove(selectedWare);
                datalist.remove(selectedWare);
                sortedList.remove(selectedWare);
                refreshTable();
            }
        });
    }

    public void update() {
        if (shop.getDBC().isConnected()) {
            datalist = shop.getAllCommissionWares();
            sortedList.removeAll(datalist);
            datalist.stream().forEach((ware) -> {
                sortedList.add(ware);
            });
            sellers.removeAll(shop.getAllSellers());
            sellers.clear();
            sellers.addAll(shop.getAllSellers());
            cats.removeAll(shop.getCategories(false));
            cats.clear();
            cats.addAll(shop.getCategories(false));
            table.setItems(sortedList);
        }
    }

    void refreshTable() {
        final List<CommissionWare> items = table.getItems();
        if (items == null || items.isEmpty()) {
            return;
        }

        final CommissionWare item = table.getItems().get(0);
        items.remove(0);
        Platform.runLater(() -> {
            items.add(0, item);
        });
    }

    private void selectedWare(CommissionWare selectThis) {
        if (selectThis != null) {
            selectedWare = selectThis;
        }
    }

    private void setupComboBox() {
        categoryCombo = new ComboBox<>();
        categoryCombo.setPromptText("Vælg Kategori");
        categoryCombo.setItems(cats);
        categoryCombo.getStyleClass().add("combobox");
        categoryCombo.setCellFactory((comboBox) -> {
            return new ListCell<Category>() {
                @Override
                protected void updateItem(Category item, boolean empty) {
                    super.updateItem(item, empty);

                    if (item == null || empty) {
                        setText(null);
                    } else {
                        setText(item.getName());
                    }
                }
            };
        });
        categoryCombo.setConverter(new StringConverter<Category>() {
            @Override
            public String toString(Category category) {
                if (category == null) {
                    return null;
                } else {
                    return category.getName();
                }
            }

            @Override
            public Category fromString(String personString) {
                return null;
            }
        });
        categoryCombo.setOnAction(event -> {
            Category selected = categoryCombo.getSelectionModel().getSelectedItem();
            sortedList.clear();
            datalist.stream().filter((ware) -> (selected.equals(cats.get(0)) || ware.getCategory().equals(selected))).forEach((ware) -> {
                sortedList.add(ware);
            });
            table.setItems(sortedList);
        });
    }

}//end of class
